/**
 * 
 */
package t4j.concurrency;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class TaskPortion implements Runnable{
	private static int counter = 0;
	private final int id = counter++;
	private static Random rand = new Random(47);
	private final CountDownLatch latch;
	

	public TaskPortion(CountDownLatch latch) {
		this.latch = latch;
	}

	public void doWork() throws InterruptedException{
		TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
		
		System.out.println(this + "complated");
	}

	@Override
	public void run() {
	
		try {
			doWork();
			latch.countDown();//-1
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}
	}
	
	@Override
	public String toString() {
		return String.format("%1$-3d", id);
	}
}

class WaitingTask implements Runnable{
	private static int counter = 0;
	private final int id = counter++;
	private final CountDownLatch latch;
	
	public WaitingTask(CountDownLatch latch) {
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			latch.await();
			System.out.println("Latch barrier passed for " + this);
		} catch (InterruptedException e) {
			System.out.println(this + " interrupted");
		}		
	}
	
	@Override
	public String toString() {
		return String.format("WaitingTask %1$-3d", id);
	}
}

public class CountDownLatchDemo {
	
	static final int SIZE = 10;
	
	public static void main(String[] args) {
		
		ExecutorService exec = Executors.newCachedThreadPool();
		
		CountDownLatch latch = new CountDownLatch(SIZE);//初始化这个数值
		
		for(int i = 0 ; i < 10 ; i++)
			exec.execute(new WaitingTask(latch));//10个等待任务
		
		for(int i = 0 ; i < SIZE; i++)
			exec.execute(new TaskPortion(latch));//SIZE个任务
		
		System.out.println("Launched all tasks");
		
		exec.shutdown();
	}
}
